開発時のDynamoDB環境としてDynamoDB Localを用いた際に行なったノウハウを公開します。
はじめに
好物はインフラとフロントエンドのかじわらゆたかです。 現在私が構築を行っているサービスでは、DynamoDBをデータストアとして用いています。
開発時に開発者各々に開発用のDynamoDBのテーブルを作成すると、 テーブル名の重複やコストの問題が発生してしまいます。 これらの問題を回避するため、開発時にはDynamoDB Localを用いて開発を進めました。 それらの手法についてお伝えします。
環境は以下の環境で実施しております。
- Mac OS X High Sierra 10.13.4
- java version "1.8.0_162"
- curl 7.54.0
- aws-cli 1.15.7
- UnZip 6.00
- Node.js v8.10.0
DynamoDBのテーブル定義を作成する
こちらはAWS CLIのスケルトンJSONを作成し、それを用いて作成します。
$ aws dynamodb create-table --generate-cli-skeleton > skel_dynamodb_create-table.json
上記で作成されたjsonに対して、項目やテーブル名等を設定していきます。
今回の例としては以下の様なJSONを作成しました。
{ "AttributeDefinitions": [ { "AttributeName": "UserID", "AttributeType": "S" } ], "TableName": "user", "KeySchema": [ { "AttributeName": "UserID", "KeyType": "HASH" } ], "ProvisionedThroughput": { "ReadCapacityUnits": 5, "WriteCapacityUnits": 5 } }
DynamoDB Localを立ち上げる
DynamoDB Localは開発環境としてAWSが提供している開発環境です。 Jarファイルとして提供されているため、開発時にインターネットへの接続が必要ありません。 そのため、プロビジョニングされたスループットやデータストレージ、データ転送料金を節約できることになります。
立ち上げるスクリプトとしては以下の様な内容を用いています。
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" mkdir ${SCRIPT_DIR}/_work if [ ! -f ${SCRIPT_DIR}/_work/dynamodb_local_latest.zip ]; then curl https://s3-ap-northeast-1.amazonaws.com/dynamodb-local-tokyo/dynamodb_local_latest.zip -o ${SCRIPT_DIR}/_work/dynamodb_local_latest.zip cd ${SCRIPT_DIR}/_work && unzip ./dynamodb_local_latest.zip cd ${SCRIPT_DIR}/_work && java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb fi cd ${SCRIPT_DIR}/_work && java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
このスクリプトを動かすことでローカル環境の8000番ポートでDynamoDB Localが立ち上がります。
DynamoDB Localにテーブルを作成する
DynamoDB のDDLとして作成したJSONファイルを用いて、AWS CLIを用いてテーブルを作成します。
AWS CLIからDynamoDB Localを用いる場合は、--endpoint-url
を用います。
aws dynamodb create-table --cli-input-json file://user.json --endpoint-url http://localhost:8000
この時気をつける必要があるのは、--endpoint-url
のオプションの付与を必ず行うことです。
このオプションの付与を行わないと、ローカル環境のDynamoDB Localではなく、AWS環境上のDynamo DBに対してのテーブル作成を行うことになります。
実行結果は以下のようになります。
$ aws dynamodb create-table --cli-input-json file://user.json --endpoint-url http://localhost:8000 { "TableDescription": { "AttributeDefinitions": [ { "AttributeName": "UserID", "AttributeType": "S" } ], "TableName": "user", "KeySchema": [ { "AttributeName": "UserID", "KeyType": "HASH" } ], "TableStatus": "ACTIVE", "CreationDateTime": 1525686945.598, "ProvisionedThroughput": { "LastIncreaseDateTime": 0.0, "LastDecreaseDateTime": 0.0, "NumberOfDecreasesToday": 0, "ReadCapacityUnits": 5, "WriteCapacityUnits": 5 }, "TableSizeBytes": 0, "ItemCount": 0, "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/user" } }
TableArnがddblocal:000000000000となっており、DynamoDB Localを参照していることがわかります。
DynamoDB Localのテーブル情報を参照する管理画面を立ち上げる
DynamoDB Localはテーブル内のデータを参照するUIが存在しないため、別途用意する必要があります。 DynamoDB adminというツールを用いてテーブルのデータを参照します。
{ "name": "dynamodb-local-admin", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "better-npm-run start", "pre-start": "npm install" }, "betterScripts": { "start": { "command": "dynamodb-admin", "env": { "DYNAMO_ENDPOINT": "http://localhost:8000" } } }, "author": "", "license": "ISC", "dependencies": { "dynamodb-admin": "^1.12.0", "better-npm-run": "^0.1.0" } }
上記のpackage.jsonを作成し、npm start
で8001番ポートでDynamoDB Localを参照する管理画面が立ち上がります。
AWS SDK for Python (Boto3)を用いてDynamoDB Localへの操作を行う
PythonのAWS SDK実装であるBoto3を用いてDynamoDB Localへの操作を行います。
今回の方針としては、環境変数DYNAMODB_ENDPOINT
に対して値が設定されている際は、設定されたエンドポイント(DynamoDB Local)を用い、設定されていない場合は、DynamoDBを用いることにします。
以下のコードではboto3がdefaultのprofileを参照するので、 項目自体は空で良いのでdefaultのprofileの作成を行なっておく必要があります。
import os import uuid import boto3 endpoint_url = os.getenv('DYNAMODB_ENDPOINT', None) dynamodb = boto3.resource('dynamodb', endpoint_url=endpoint_url) user_table = dynamodb.Table('user') user = { "UserID": str(uuid.uuid4()), "UserName": "KAJIWARA YUTAKA" } user_table.put_item(Item=user)
上記のコードを実行した後に、先ほど構築したDynamoDB Adminで確認すると、DynamoDB Localに値が書き込まれていることがわかります。
VisualStudioCodeでPythonをデバッグする際の環境変数の設定
Pythonの実装はVisual Studio Codeを用いて行なっています。 Visual Studio Codeでは、デバッグ等を行うときの環境変数の設定を行うことが可能です。
デバッグ用の設定ファイル(launch.json)を作成した際に、envというキーでオブジェクトを作成し、その中に設定したい環境変数と値を設定します。
今回の例の場合はDYNAMODB_ENDPOINT
という環境変数を作成したいので、以下のようになります。
{ "version": "0.2.0", "configurations": [ { "name": "Python: Current File", "type": "python", "request": "launch", "program": "${file}", "env": { "DYNAMODB_ENDPOINT": "http://localhost:8000" }, } ] }
まとめ
DynamoDB Localを用いての開発方法についてまとめました。 DynamoDB LocalとDynamoDB Adminを用いることでGUIで確認しながらDynamoDB を用いた実装を進めていくことが可能です。